package net;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Andrea
 */
public final class PacketBuffer {

    private final InputStream is;

private final Queue<Byte> buffer;

    public PacketBuffer(InputStream is) {
        this.is = is;

        buffer = new LinkedList<>();
    }

    @SuppressWarnings({"SleepWhileInLoop", "SleepWhileHoldingLock"})
    public synchronized Packet getNext() throws IOException {
        
        while (is.available() < 9 && buffer.size() < 11) {
            try {
                
                Thread.sleep(1);
            } catch (InterruptedException ex) {
                Logger.getLogger(PacketBuffer.class.getName()).log(Level.SEVERE, null, ex);
                
                return null;
            }
        }
        byte b[] = new byte[is.available()];
        is.read(b);
        for (int i = 0; i < b.length; i++) {
            buffer.add(b[i]);  
        }
        
//        do {
//            int read = is.read();
//            
//            if(read == -1){
//                throw new IOException("End of the stream reached");
//            }
//            
//            buffer.add((byte)read);
//            
//            System.out.println("1 " + is.available());
//        } while(is.available() > 0);
        
        short et = (short) ((buffer.poll()<< 8) + (buffer.poll()));

        int length = (buffer.poll() << 24) + (buffer.poll() << 16) + (buffer.poll() << 8) + buffer.poll();
        
        Packet.DataType dc = Packet.DataType.findByValue(buffer.poll());

        byte data[] = new byte[length];

        for (int i = 0; i < length; i++) {
            data[i] = buffer.poll();
        }

        int hash = (buffer.poll() << 24) + (buffer.poll() << 16) + (buffer.poll() << 8) + buffer.poll();

//        if (Packet.generateHash(et, dc, data) != hash) {
//            throw new RuntimeException("the Packet is corrupted");
//        }
        
        Packet p = new Packet(et, dc, data);
        System.out.println("reading");
        return p;
    }
    
    public void debugBuffer(){
        System.out.println("buffer \n \n");
        
        for (Byte b : buffer) {
            System.out.print(b + " ");
        }
        
        System.out.println("\n \n");
    }
}
